:- module(viewable).
:- reexport viewable_create / 2, viewable_create / 3, viewable_create / 4, viewable / 1, viewable_size / 2, viewable_type / 2, viewable_expand / 3, viewable_expand / 4 from vc_support.
:- comment(summary, "Module for the management of viewables: arrays for visualisation").
:- comment(author, "Josh Singer").
:- comment(copyright, "Parc Technologies Ltd. and IC-Parc 2001").
:- comment(desc, html("<P> Module for the management of\n           <EM>viewables</EM>. These are logical, multidimensional\n           arrays and graph structures whose elements can be accessed\n           globally for visualisation purposes. The creation,\n           destruction and modification of viewables and their\n           contents can be monitored by visualisation clients. </P>\n\n           <P> The library <CODE>lib(graph_algorithms)</CODE> contains\n           predicates to create and manipulate graph structures.\n\n           <P> Viewables are created using <CODE>viewable_create/2/3/4</CODE>\n            and last until this call is\n           backtracked over. During its lifetime, a viewable is said to be\n           <EM>existent</EM>. This can be tested with\n           <CODE>viewable/1</CODE>, which can also be used to enumerate all\n           existent viewables. </P>\n\n           <P> One or more of the dimensions of a viewable can\n           optionally be flexible in size while the viewable is\n           existent. This allows new elements to be added to the\n           viewable, using <CODE>viewable_expand/3/4</CODE>. The\n           <EM>fixity</EM> of a dimension denotes whether it is fixed\n           or flexible. In the case of graph typed viewables, the\n           fixity refers to the ability to add new nodes and/or edges\n           to the graph.  Currently only <EM>fixed</EM> graphs are\n           supported.\n\n           <P> A viewable is given a type when it is created. For\n           array types, this specifies the number of dimensions, the\n           fixity of each dimension and the type of viewable elements\n           which the viewable can contain. For graph types, this\n           simply specifies whether the graph structure (number of\n           nodes, edge direction etc) may be modified during the\n           viewables lifetime. An existent viewable's type can be\n           retrieved using <CODE>viewable_type/2</CODE>, and its\n           current sizes of the dimensions can be retrieved using\n           <CODE>viewable_size/2.</code> </P>\n\n           <h3>Optimised behaviour without visualisation</h3> Visualisation\n           clients can only monitor viewables whose creation occurs\n           <em>after</em> they register. When there are no registered\n           visualisation clients, for efficiency purposes no data on\n           viewables is stored and so the predicates in this module behave\n           slightly differently from normal:\n\n           <ul>\n\n           <li><code>viewable_create/2/3/4</code> and\n           <code>viewable_expand/3/4</code> succeed with any arguments. It is\n           therefore reasonable to leave these predicates in your code even\n           when not visualising.</li>\n\n           <li><code>viewable/1</code>, <code>viewable_size/2</code> and\n           <code>viewable_type/2</code> fail whatever the arguments. If\n           these predicates are used (normally they should not be\n           necessary) the possibility of failure should be taken into\n           account.</li>\n\n           </ul>\n\n")).
:- comment(viewable / 1, [amode : viewable(?), args : ["ViewableName" : "Atom or string: name of a viewable."], summary : "Test/enumerate names of all existent viewables.", desc : html("\n\n        <p><B>NOTE:</B>When there are no registered visualisation clients,\n        this predicate fails with all arguments, and has no effect.</P>\n\n\n       If <em>ViewableName</em> is instantiated, tests whether\n       <em>ViewableName</em> is the name of an existent viewable. If not,\n       <em>ViewableName</em> is successively instantiated to the names of all\n       existent viewables."), fail_if : "Fails if ViewableName is not / cannot be instantiated to the name of an existent viewable.", exceptions : [4 : "ViewableName is not an atom, string or free variable"], resat : yes, eg : "\n\n[Assuming that at least one visualisation client is registered]\n\n     Success:\n\n     viewable_create(my_viewable, [X,Y,Z], array([fixed], any)), \n       viewable(my_viewable).\n\n\n     Failure:\n\n     viewable(non_viewable)\n\n\n     Exception raised:\n\n     viewable(123).\n     [raises error 4].\n", see_also : [viewable_create / 2, viewable_create / 3]]).
:- comment(viewable_create / 2, [amode : viewable_create(?, +), args : ["ViewableName" : "A string or atom; the name of the new viewable.", "Elements" : "A possibly nested list or array (as created for example by dim/2)."], summary : "Create a viewable.", eg : "\n\n[Assuming that at least one visualisation client is registered]\n\n       Success:\n\n       viewable_create(viewable1, [X, Y, Z]).\n\n       viewable_create(\"viewable1\", [](X, Y, Z)).\n\n       viewable_create(m, []).\n\n       viewable_create(var23, [[],[],[]]).\n\n       viewable_create(var315, []([]([](R, T, [E, X, Y]), \n                                     [](W, T, grok(D))), \n\t\t\t\t  []([](A, B, C),\n\t\t\t\t     [](R, E, W)))).\n\n\n\n       Exceptions raised:\n\n       viewable_create(2, [x,y,z]).\n       [gives error 4] \n\n       viewable_create(v1, [x,y,z]), \n       viewable_create(v1, [x,y,z]).\n       [gives error 1] \n\n       viewable_create(v1, _).\n       [gives error 1] \n\n\n\t\t\t\t    ", desc : html("\n\n        <p><B>NOTE:</B>When there are no registered visualisation clients,\n        this predicate succeeds with any arguments, and has no effect.</P>\n\n\tThis predicate creates a new viewable by specifying its name and\n\telements. The predicate will try to guess the number of dimensions\n\tfor the new viewable from the level of nesting in\n\t<em>Elements</em>. All dimensions are set to <code>fixed</code> so\n\tthey cannot be expanded later. The element type is set to\n\t<code>any</code>. For more control over the number and fixity of\n\tdimensions and the element type, use\n\t<code>viewable_create/3</code>.\n\n        In other ways the predicate behaves just like\n        <code>viewable_create/3</code>. See the documentation for that\n        predicate for more details. </P>"), see_also : [viewable_create / 3, viewable_expand / 3], exceptions : [4 : "ViewableName is not an atom, string or free variable.", 1 : "ViewableName is the name of an existent viewable.", 1 : "Elements is not a nested list or array."], resat : no]).
:- comment(viewable_create / 3, [amode : viewable_create(?, +, ++), args : ["ViewableName" : "A string or atom; the name of the new viewable.", "Elements" : "A list nested to at least a depth equal to the number of dimensions, an array with sufficient dimensions (as created for example by dim/2) or graph structure.", "Type" : "A ground term which is a valid viewable type. "], summary : "Create a viewable, specifying type.", eg : "\n\n[Assuming that at least one visualisation client is registered] \n\n       Success:\n\n       viewable_create(viewable1, [X, Y, Z], array([fixed], any)).\n\n       lib(fd), fd:([X, Y, Z]::1..10), \n       viewable_create(viewable1, [X, Y, Z], array([fixed], numeric_bounds)).\n\n       viewable_create(viewable1, [3.2, 5.00__5.01, 7], \n                       array([fixed], numeric_bounds)).\n\n       viewable_create(\"viewable1\", [](X, Y, Z), array([flexible], any)).\n\n       viewable_create(m, [], array([flexible], any)).\n\n       viewable_create(var23, [[],[],[]], array([fixed, flexible], any)).\n\n       viewable_create(var315, []([]([](R, T, [E, X, Y]), \n                                     [](W, T, grok(D))), \n\t\t\t\t  []([](A, B, C),\n\t\t\t\t     [](R, E, W))), \n\t\t       array([fixed, flexible, flexible], any)).\n\n       viewable_create(m,[[],[],[]],array([fixed, flexible, flexible],any)).\n       [Note: the initial size of this viewable would be 3 x 0 x 0]\n\n       lib(graph_algorithms),\n       make_graph(3,[e(1,2,e1), e(2,3,e2), e(1,3,e3)], Graph),\n       viewable_create(m, Graph, graph(fixed)).\n       [Note: the node will be labelled with the numbers '1', '2' and '3',\n       the edges labelled 'e1', 'e2' and 'e3']\n       \n       lib(graph_algorithms),\n       make_graph_symbolic([](n1,n2,n3),[edge(n1,n2,e1), edge(n2,n3,e2), edge(n1,n3,e3)], Graph),\n       viewable_create(m, Graph, graph(fixed)).\n       [Note: the node will be labelled with the strings 'n1', 'n2' and 'n3',\n       the edges labelled 'e1', 'e2' and 'e3']\n\n       lib(eplex_with_ic),\n       eplex_instance(my_instance),\n       my_instance: eplex_solver_setup(min(X)),\n       viewable_create(eplex,[X,Y],array([fixed],changeable(my_instance,numeric_bounds))),\n       viewable_create(ic,[X,Y],array([fixed],numeric_bounds)),\n       my_instance: (X+Y >= 3),\n       my_instance: (X-2*Y =:= 0),\n       my_instance: eplex_solve(Cost).       \n       [Note: this creates two viewables, one showing the solution as\n        assigned by eplex, the other showing the ic bounds]\n\n       lib(s_eplex),\n       eplex_instance(my_instance),\n       my_instance: eplex_solver_setup(min(X)),\n       viewable_create(eplex,[X,Y],array([fixed],changeable(my_instance,numeric_bounds))),\n       my_instance: (X+Y >= 3),\n       my_instance: (X-2*Y =:= 0),\n       my_instance: eplex_solve(Cost).       \n       [Note: this creates a single viewable using the standalone eplex\n        library and shows how to visualise the bounds stored in the external\n        solver]\n\n\n       Exceptions raised:\n\n       viewable_create(2, [x,y,z], array([fixed], any)).\n       [gives error 4] \n\n       viewable_create(v1, [x,y,z], array([fixed], any)), \n       viewable_create(v1, [x,y,z], array([fixed], any)).\n       [gives error 1] \n\n       viewable_create(v1, _, array([fixed], any)).\n       [gives error 1] \n\n       viewable_create(v1, [x,y,g], array([fixed, fixed], any)).\n       [gives error 1] \n\n       viewable_create(v1, [x,y,x], array([], any)).\n       [gives error 1] \n\n       viewable_create(v1, [x,y,x], slorg([fixed], any)).\n       [gives error 1] \n\n       viewable_create(v1, [x,y,x], nurg).\n       [gives error 1] \n\n       viewable_create(v1, [x,y,x], numeric_bounds).\n       [gives error 5] \n\t\t\t\t    ", desc : html("\n\n        <p><B>NOTE:</B>When there are no registered visualisation clients,\n        this predicate succeeds with any arguments, and has no effect.</P>\n\n\tThis predicate creates a new viewable by specifying its name,\n\telements and type.  At present the type must be of the form\n\tarray(FixityList, ElementType) or graph(fixed) where <ul>\n\t<li>FixityList is a list with an atom <code>fixed</code> or\n\t<code>flexible</code> specifying the fixity for each\n\tdimension. The fixity denotes whether the dimension's size is\n\tfixed or may vary during the time when the viewable is\n\texistent.</li> <li>ElementType is a term which specifies the\n\ttype of the constituent viewable elements.  Currently there\n\tare two supported element types: <ul> <li><code>any</code>\n\twhich includes any ECLiPSe term</li> <li>\n\t<code>numeric_bounds</code> which includes any ground number,\n\tinteger <code>fd</code> variables, <code>ic</code> variables\n\tand <code>range</code> variables (including <code>eplex</code>\n\tand <code>ria</code> variables). </li> <li>\n\t<code>changeable(Module,Type)</code> which indicates that the\n\tvalue should be accessed through the <em>changeable</em>\n\tinterface of the given Module\n\t(eg. changeable(eplex_instance,any) indicates that the value\n\tis ths solution assigned to the variable by the given\n\teplex_instance).  The <code>Type</code> parameter can be any\n\tof the <em>other</em> ElementTypes in this list.</li> </ul>\n\t</li> </ul>\n\n\tVisualisation clients, if there are any, are notified of the new\n\tviewable when it is created. On backtracking over a call to\n\t<code>viewable_create/3</code>, the viewable is destroyed, and\n\tvisualisation clients are also notified of this. </P><P>\n\n\t<EM>ViewableName</EM> is a global handle which can be used to\n\taccess the viewable while it is existent. If <EM>ViewableName</EM>\n\tis a variable, it is instantiated to an atom. The atom is unique in\n\tthe sense that no two existent viewables will share the same name\n\tat any point during the lifetime of the ECLiPSe engine.</P><P>\n\n        For array types, the number of dimensions is specified by the\n        length of <em>FixityList</em> in <em>Type</em>. <EM>Elements</EM>\n        is a nested list or array. The depth of nesting is usually at\n        least the number of dimensions specified in <em>FixityList</em>.\n        However, dimensions with an initial size of 0 are also\n        allowed, and these can implicitly contain an arbitrary number\n        of further dimensions, also assumed to be of initial size\n        0. So for example an <em>Elements</em> argument of\n        <code>[[],[],[]]</code> or <code>[]([],[],[])</code> can be\n        used with a <em>FixityList</em> of <code>[fixed,\n        flexible]</code>, giving an initial size of 3 x 0, or used\n        with a <em>FixityList</em> of <code>[fixed, flexible,\n        flexible, flexible]</code>, giving an initial size of 3 x 0 x\n        0 x 0. Be sure to make any initially empty dimensions\n        flexible!  <em>Elements</em> must also be regular: each inner\n        list / array at the same level of nesting must be the same\n        length, down to the level equal to the number of dimensions.\n\n        <p><code>viewable_create/3</code> sets location names (e.g. row/column\n        names) to \"1\", \"2\", etc. For more control over location names use \n        <code>viewable_create/4</code>.</P>"), see_also : [viewable_create / 2, viewable_create / 4, viewable_expand / 3, graph_algorithms : make_graph / 3], exceptions : [4 : "ViewableName is not an atom, string or free variable.", 1 : "ViewableName is the name of an existent viewable.", 1 : "Elements is not a regular nested list or array with enough dimensions.", 1 : "Type is not a ground valid type.", 5 : "One of the viewable elements violates the element type."], resat : no]).
:- comment(viewable_create / 4, [amode : viewable_create(?, +, ++, ++), args : ["ViewableName" : "A string or atom; the name of the new viewable.", "Elements" : "A list nested to at least a depth equal to the number of dimensions, or an array with sufficient dimensions (as created for example by dim/2) or a graph structure.", "Type" : "A ground term which is a valid viewable type. ", "LocNamesList" : "A list of lists of strings (location names) or a list of semantic markup terms from graph structures."], summary : "Create a viewable, specifying both type and location names.", eg : "\n\n            To create a 2 x 3 viewable, you could do:\n\n            viewable_create(v1, [[A,B,C], [D,E,F]], \n                            array([fixed, fixed], any), \n                            [[\"foo\", \"bar\"], [\"tom\", \"dick\", \"harry\"]]).\n\n            This would have two rows (named \"foo\" and \"bar\") each\n\t    with three columns (named \"tom\", \"dick\" and\n\t    \"harry\").\n\n            To create a graph viewable where node names are attached\n            to node labels and edge info fields are attached to edge\n            lables (ie info(1,foo(A)), info(2,foo(B)) and\n            info(3,foo(C)) as per viewable_create/3).\n\n            lib(graph_algorithms),\n            make_graph_symbolic([](n1,n2,n3),\n                                [edge(n1,n2,info(1,foo(A)),\n                                 edge(n2,n3,info(2,foo(B)),\n                                 edge(n1,n3,info(3,foo(C))], Graph),\n            viewable_create(v2, Graph, graph(fixed),\n                            [node_property([0->[name('node names'), label]]),\n                             edge_property([0->[name('edge info'), label]])\n                            ]).\n                            \n\n            To create a graph where the edges are labelled with the\n            second argument of the edge info structure. (ie with the\n            structures foo(A), foo(B) and foo(C))\n\n            lib(graph_algorithms),\n            make_graph_symbolic([](n1,n2,n3),\n                                [edge(n1,n2,info(1,foo(A)),\n                                 edge(n2,n3,info(2,foo(B)),\n                                 edge(n1,n3,info(3,foo(C))], Graph),\n            viewable_create(v2, Graph, graph(fixed),\n                            [node_property([0->[name('node names'), label]]),\n                             edge_property([2->[name('edge info'), label]])\n                            ]).\n\n            \n            To create a graph where the edges are labelled with the\n            first argument of the nested structure at the second\n            argument of the edge info structure. (ie with the\n            variables A, B and C)\n\n            lib(graph_algorithms),\n            make_graph_symbolic([](n1,n2,n3),\n                                [edge(n1,n2,info(1,foo(A)),\n                                 edge(n2,n3,info(2,foo(B)),\n                                 edge(n1,n3,info(3,foo(C))], Graph),\n            viewable_create(v2, Graph, graph(fixed),\n                            [node_property([0->[name('node names'), label]]),\n                             edge_property([[2,1]->[name('edge info'), label]])\n                            ]).\n            ", desc : html("\n\n        <p><B>NOTE:</B>When there are no registered visualisation clients,\n        this predicate succeeds with any arguments, and has no effect.</P>\n\n        <p>This predicate works exactly the same as\n        <code>viewable_create/3</code> except that you have the added\n        ability to set location names (e.g. row/column names) for\n        arrays and to indicate which elements of the edge info\n        structure should be attached to edge labels for graphs.\n\n        <p>For array type viewables the <em>LocNamesList</em> argument\n        should be a list as long as the number of dimensions in the\n        viewable. The ith element <em>LocNames</em> of\n        <em>LocNamesList</em> should be a list whose length is equal\n        to the size of the ith dimension of the new viewable. The jth\n        element of <em>LocNames</em> should be a ground string and\n        this will become the name of the jth location of the ith\n        dimension.  </P>\n\n        <p>For graph type viewables the <em>LocNamesList</em> argument\n        should be a list of the following form.\n\n<pre>\n[\n node_property([0->[name(NodeInfoName), label]]),\n edge_property([Index->[name(EdgeInfoName), label]])\n]\n</pre>\n\n        Where <code>NodeInfoName</code> is a meaningful name for the\n        information to be displayed at the nodes in the graph.  eg. If\n        the graph represented a computer network, the nodes may show\n        individual machine names. In such a case, <code>\"machine\n        name\"</code> would be a likely candidate for the NodeInfoName\n        argument.  Similarly <code>EdgeInfoName</code> refers to the\n        information associated with edge labels.\n\n        <p>The <code>Index</code> argument specifies which part of the\n        edge info field should be shown on edges. 0:The whole edge\n        info structure.  N:The Nth argument of the edge info\n        structure.  [...,I,J,K]:The Kth argument of the Jth argument\n        of the Ith argument... of the edge info structure. See below\n        for examples.\n\n        <p>For a more detailed description of creating viewables, refer to the\n        documentation for <code>viewable_create/3</code>.</P>\n\n\n"), see_also : [viewable_create / 2, viewable_create / 3, viewable_expand / 4, graph_algorithms : make_graph / 3], exceptions : [4 : "ViewableName is not an atom, string or free variable.", 1 : "ViewableName is the name of an existent viewable.", 1 : "Elements is not a regular nested list or array with enough dimensions.", 1 : "Type is not a ground valid type.", 5 : "One of the viewable elements violates the element type.", 5 : "LocNamesList is not a correctly-sized list of correctly-sized lists of strings."], resat : no]).
:- comment(viewable_expand / 3, [amode : viewable_expand(++, ++, +), args : ["ViewableName" : "A string or atom; the name of an existent viewable", "DimensionNumber" : "An integer: the number of the dimension to be enlarged.", "ExtraElements" : "A nested list or an array of the right size/dimensions, containing the new viewable elements."], summary : "Expand a dimension of a viewable by adding new elements.", desc : html("\n\n        <p><B>NOTE:</B>When there are no registered visualisation clients,\n        this predicate succeeds with any arguments, and has no effect.</P>\n\n\n\n      <p>A viewable which has a flexible dimension (see\n      <code>viewable_create/3</code>) may be expanded along that dimension\n      by adding new elements. The dimension must have been declared\n      flexible when the viewable was first created. The\n      <em>ExtraElements</em> argument is of the same format as the\n      <em>Elements</em> argument of <code>viewable_create/3</code>.</p>\n\n      <p>The number and size of the dimensions of <em>ExtraElements</em>\n      depends on the number and size of dimensions of the viewable being\n      expanded. <em>ExtraElements</em> should have one less dimension than\n      the viewable -- dimension <em>DimensionNumber</em> should be\n      missing. The remaining dimensions should have the same sizes as the\n      corresponding dimensions in the viewable.</p>\n\n      <p>For example, a viewable of size 3 x 0 x 0 with all dimensions\n      flexible, can be expanded along dimenson 3 using an\n      <em>ExtraElements</em> argument of []([], [], []) which has size 3 x\n      0. The viewable would then have size 3 x 0 x 1. It could then be\n      expanded along dimension 1 using <code>[]</code> as\n      <em>ExtraElements</em> since <code>[]</code> can implicitly have the\n      size 0 x 1. The viewable would then have the size 4 x 0 x 1. Then\n      dimension 2 could be expanded using <code>[[W],[X],[Y],[Z]]</code>\n      for <em>ExtraElements</em> as this has size 4 x 1. The final size of\n      the viewable would then be 4 x 1 x 1.</p>\n\n      <p>The extra viewable elements must each also conform to the element\n      type specified when the viewable was created.</p>\n\n      <p> Note that when the viewable has one dimension, the\n      <em>ExtraElements</em> argument will simply become the new element\n      itself.</p>\n\n      <p><code>viewable_expand/3</code> sets the name of the new location \n      (e.g. the column or row name) to its number as a string. For example, \n      adding a third row using <code>viewable_expand/3</code> will result\n      in the row being named \"3\". For more control over the name of the new\n      location use <code>viewable_expand/4</code>.<p>\n\n"), fail_if : "Fails if ViewableName is not the name of an existent viewable, or if the requested dimension of the viewable is not flexible.", exceptions : [4 : "ViewableName is not a string or atom", 5 : "DimensionNumber is not a ground integer", 6 : "DimensionNumber is not positive, or exceeds the viewable's number of dimensions", 1 : "ExtraElements is not a regular nested list or array of the correct size/dimensions", 5 : "ExtraElements contains elements which do not conform to the element type of the viewable"], resat : no, eg : "\n\n[Assuming that at least one visualisation client is registered]\n\n       Success:\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n       \t               array([flexible, fixed], any)), \n       viewable_expand(v1, 1, [R, S, T]).\n\n       lib(fd), fd:([X, Y, Z, R] :: 1..10), \n       viewable_create(v1, [X, Y, Z], array([flexible], numeric_bounds)),\n       viewable_expand(v1, 1, R).\n       \n       viewable_create(v1, []([](X, Y, Z), [](A, B, C)), \n       \t               array([fixed, flexible], any)), \n       viewable_expand(v1, 2, [R, S]).\n\n\n       viewable_create(v1, [[], [], []], \n\t\t       array([flexible, flexible, flexible], any)),\n       viewable_expand(v1, 3, []([], [], [])), \n       viewable_expand(v1, 1, []), \n       viewable_expand(v1, 2, [[W], [X], [Y], [Z]]),  \n       viewable_size(v1, Size).\n       [gives Size = [4,1,1]]\n\n       viewable_create(v1, [], array([flexible], any)), \n       viewable_expand(v1, 1, F), \n       viewable_expand(v1, 1, G),\n       viewable_size(v1, Size).\n       [gives Size = [2]]\n       \n       \n\n\n       Failure:\n\n       viewable_expand(no, 2, [R, S]).\n\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n\t               array([fixed, flexible], any)), \n       viewable_expand(v1, 1, [R, S, T]).\n\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n\t               array([flexible, fixed], any)), \n       viewable_expand(v1, 2, [R, S]).\n\n\n\n       Exceptions raised:\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n\t               array([flexible, fixed], any)), \n       viewable_expand(_, 1, [R, S, T]).\n       [gives error 4]\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n\t               array([flexible, fixed], any)), \n       viewable_expand(v1, _, [R, S, T]).\n       [gives error 5]\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n                       array([flexible, fixed], any)), \n       viewable_expand(v1, 3, [R, S, T]).\n       [gives error 6]\n\n       viewable_create(v1, []([](X, Y, Z), [](A, B, C)), \n\t               array([fixed, flexible], any)), \n       viewable_expand(v1, 2, _).\n       [gives error 1]\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n\t               array([flexible, fixed], any)), \n       viewable_expand(v1, 1, [R, S, T, Q]).\n       [gives error 1]\n\n       lib(fd), fd:([X, Y, Z] :: 1..10), \n       viewable_create(v1, [X, Y, Z], array([flexible], numeric_bounds)),\n       viewable_expand(v1, 1, an_atom)\n       [gives error 5]\n\n\n\n", see_also : [viewable_expand / 4, viewable_create / 3, viewable_size / 2, viewable_type / 2]]).
:- comment(viewable_expand / 4, [amode : viewable_expand(++, ++, +, ++), args : ["ViewableName" : "A string or atom; the name of an existent viewable", "DimensionNumber" : "An integer: the number of the dimension to be enlarged.", "ExtraElements" : "A nested list or an array of the right size/dimensions, containing the new viewable elements.", "LocName" : "A string: the name of the new location."], summary : "Expand a dimension of a viewable by adding new elements, specifying the name of the new location.", desc : html("\n\n        <p><B>NOTE:</B>When there are no registered visualisation clients,\n        this predicate succeeds with any arguments, and has no effect.</P>\n\n        <p>This predicate behaves exactly the same as <code>viewable_expand/3</code> except that you have the added ability to name the new location of the expanded dimension. <em>LocName</em> is a string which becomes the name for the new location. </p>\n\n        For more details on expanding viewables, see the documentation for <code>viewable_expand/3</code>. \n\n"), fail_if : "Fails if ViewableName is not the name of an existent viewable, or if the requested dimension of the viewable is not flexible.", exceptions : [4 : "ViewableName is not a string or atom", 5 : "DimensionNumber is not a ground integer", 6 : "DimensionNumber is not positive, or exceeds the viewable's number of dimensions", 1 : "ExtraElements is not a regular nested list or array of the correct size/dimensions", 5 : "ExtraElements contains elements which do not conform to the element type of the viewable", 5 : "LocName is not a string"], resat : no, eg : "\n\n[Assuming that at least one visualisation client is registered]\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n       \t               array([flexible, fixed], any)), \n       viewable_expand(v1, 1, [R, S, T], \"barg\").\n\n       This will add to the 2 x 3 viewable a third row, named \"barg\".\n\n       viewable_create(v1, [[X, Y, Z], [A, B, C]], \n       \t               array([fixed, flexible], any)), \n       viewable_expand(v1, 2, [Q, P], \"zatch\").\n\n       This will add to the 2 x 3 viewable a fourth column, named \"zatch\".\n\n\n", see_also : [viewable_expand / 3, viewable_create / 4, viewable_size / 2, viewable_type / 2]]).
:- comment(viewable_size / 2, [amode : viewable_size(++, ?), args : ["ViewableName" : "A string or atom: the name of an existent viewable", "SizeList" : "A list of integers: each is the current size of a dimension"], summary : "Query the sizes of the dimensions of an existent viewable.", desc : html(" <p><B>NOTE:</B>When there are no registered visualisation clients, this\n        predicate fails with all arguments, and has no effect.</P>\n\n            <p>If <em>ViewableName</em> is the name of an existent viewable,\n\t    <em>SizeList</em> is unified with a list of integers, each\n\t    integer being the number of elements in one of the viewable's\n\t    dimensions."), fail_if : "Fails if ViewableName is not\n\t    instantiated to the name of an existent viewable, or if\n\t    SizeList fails to unify with the list of dimension sizes.\n\n", exceptions : [4 : "ViewableName is not a string or an atom", 5 : "SizeList is not a free variable or list or contains one or more elements which is not a free variable or an integer"], resat : no, eg : "\n\n[Assuming that at least one visualisation client is registered]\n\n\tSuccess:\n\n\tviewable_create(v1, [], \n\t\t\tarray([flexible, flexible, flexible], any)), \n\tviewable_size(v1, X).\n        [gives X = [0,0,0]]\n\n\tviewable_create(v1, []([](R,S), [](Q,W)), \n\t\t\tarray([fixed, fixed], any)), \n\tviewable_size(v1, X).\n        [gives X = [2,2]]\n\n\n\tFailure:\n\n\tviewable_size(no, X).\n\n\tviewable_create(v1, []([](R,S), [](Q,W)), \n\t\t\tarray([fixed, fixed], any)), \n\tviewable_size(v1, [1,2]).\n\n\n\n        Exceptions raised:\n\n\tviewable_size(_, X).\n        [gives error 4]\n\n\tviewable_size(123, X).\n        [gives error 4]\n\n\tviewable_create(v1, [X, Y, Z]), \n\tviewable_size(v1, q).\n        [gives error 5]\n\n\tviewable_create(v1, [X, Y, Z]), \n\tviewable_size(v1, [a]).\n        [gives error 5]\n\n", see_also : [viewable_create / 3, viewable_expand / 3, viewable_type / 2]]).
:- comment(viewable_type / 2, [amode : viewable_type(++, ?), args : ["ViewableName" : "A string or atom: the name of an existent viewable", "Type" : "The type of the viewable. "], summary : "Query the type of an existent viewable.", desc : html("\n\n        <p><B>NOTE:</B>When there are no registered visualisation clients,\n        this predicate fails with all arguments, and has no effect.</P>\n\n        <p>If <em>ViewableName</em> is the name of an existent viewable,\n        <em>Type</em> is unified with its type. See\n        <code>viewable_create/3</code> for a discussion of valid viewable\n        types.</p>\n\n\n"), fail_if : "Fails if ViewableName is not instantiated to the name of an existent viewable, or if Type fails to unify with the viewable's type.", exceptions : [4 : "ViewableName is not a string or an atom"], resat : no, eg : "\n\n[Assuming that at least one visualisation client is registered]\n\n\tSuccess:\n\n\tviewable_create(v1, []([](R,S), [](Q,W)), \n\t\t\tarray([fixed, fixed], any)), \n\tviewable_type(v1, X).\n\n        [gives X = array([fixed, fixed], any)]\n\n\n\tFailure:\n\n\tviewable_create(v1, []([](R,S), [](Q,W)), \n\t\tarray([fixed, fixed], any)), \n\tviewable_type(v1, q).\n\n\n\tExceptions raised:\n\n\tviewable_create(v1, []([](R,S), [](Q,W)), \n\t\tarray([fixed, fixed], any)), \n\tviewable_type(123, _).\n        [gives error 4]\n\n", see_also : [viewable_create / 3, viewable_size / 2, viewable_expand / 3]]).
